{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is a supplementary file for the tutorial this week and can be safely ignored\n",
    "solutions will also be posted for this at the end of the week if you are interested\n",
    "if you find any errors please notify me at omarghattas1991@gmail.com"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Aim: We are going to explore three fundamental algorithms that are the basis for deep learning:\n",
    "1. the Perceptron training rule\n",
    "2. Gradient Descent\n",
    "3. Stochastic Gradient Descent\n",
    "\n",
    "At the end of this lab you should be comfortable with perceptron training and the basics of \n",
    "gradient descent -> be able to start thinking about neural networks and building them from scratch \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "np.random.seed(43)\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Helper Functions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def plot_scatter(X, y, w):\n",
    "    pos_points = X[np.where(y==1)[0]]\n",
    "    neg_points = X[np.where(y==-1)[0]]\n",
    "    plt.scatter(pos_points[:, 1], pos_points[:, 2], color='blue')\n",
    "    plt.scatter(neg_points[:, 1], neg_points[:, 2], color='red')\n",
    "    xx = np.linspace(-6,6)\n",
    "    yy = -w[0]/w[2] - w[1]/w[2] * xx\n",
    "    plt.plot(xx, yy, color='orange')\n",
    "    \n",
    "    ratio = (w[2]/w[1] + w[1]/w[2])\n",
    "    xpt = (-1*w[0] / w[2]) * 1/ratio\n",
    "    ypt = (-1*w[0] / w[1]) * 1/ratio\n",
    "    \n",
    "    plt.axes().arrow(xpt, ypt, w[1], w[2], head_width=0.2, color='orange')\n",
    "    plt.axis('equal')\n",
    "    plt.show()\n",
    "    \n",
    "#plot_scatter(X, y, w=np.array([0,-1,3]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Applications/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: RuntimeWarning: covariance is not symmetric positive-semidefinite.\n",
      "  \n",
      "/Applications/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:3: RuntimeWarning: covariance is not symmetric positive-semidefinite.\n",
      "  This is separate from the ipykernel package so we can avoid doing imports until\n"
     ]
    }
   ],
   "source": [
    "def generate_data(n=20):\n",
    "    dist_01 = np.random.multivariate_normal(np.array([2,2]), np.array([[1,0.9],[0.5,1]]), n)\n",
    "    dist_02 = np.random.multivariate_normal(np.array([-2,-2]),np.array([[1,0],[0.3,1]]), n)\n",
    "    X = np.concatenate((np.ones(2*n).reshape(-1,1), np.concatenate((dist_01, dist_02))), axis=1)\n",
    "    y = np.concatenate((np.ones(n), -1*np.ones(n)))\n",
    "    shuffle_idx = np.random.choice(2*n, size=2*n, replace=False)\n",
    "    X = X[shuffle_idx]\n",
    "    y = y[shuffle_idx]\n",
    "    return X, y\n",
    "X, y = generate_data()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "## Perceptron Training Rule"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "def train_perceptron(X, y, eta=1):\n",
    "    w = np.array([-2,-1,3])\n",
    "    nmb_data = X.shape[0]\n",
    "    '''\n",
    "    your code here\n",
    "    '''\n",
    "    #iteratively train model, until there is no error, if there is an error, retrain the model\n",
    "    while True:\n",
    "        count = 0\n",
    "        for i in range(nmb_data):\n",
    "            if(((y[i] * w.T) @ X[i]) <= 0):\n",
    "                w = w + eta * y[i] * X[i]\n",
    "                plot_scatter(X, y, w)\n",
    "                print(\"Iteration {0}, w is {1}\".format(count,w))\n",
    "                count = 0\n",
    "            count += 1\n",
    "            print(\"Iteration {0}, w is {1}\".format(count,w))\n",
    "            if(count > nmb_data):\n",
    "                print('converged')\n",
    "                plot_scatter(X, y, w)\n",
    "                return\n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Iteration 1, w is [-2 -1  3]\n",
      "Iteration 2, w is [-2 -1  3]\n",
      "Iteration 3, w is [-2 -1  3]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/Applications/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:2: RuntimeWarning: covariance is not symmetric positive-semidefinite.\n",
      "  \n",
      "/Applications/anaconda3/lib/python3.7/site-packages/ipykernel_launcher.py:3: RuntimeWarning: covariance is not symmetric positive-semidefinite.\n",
      "  This is separate from the ipykernel package so we can avoid doing imports until\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Iteration 3, w is [-1.9        -0.79216168  3.12332088]\n",
      "Iteration 1, w is [-1.9        -0.79216168  3.12332088]\n",
      "Iteration 2, w is [-1.9        -0.79216168  3.12332088]\n",
      "Iteration 3, w is [-1.9        -0.79216168  3.12332088]\n",
      "Iteration 4, w is [-1.9        -0.79216168  3.12332088]\n",
      "Iteration 5, w is [-1.9        -0.79216168  3.12332088]\n",
      "Iteration 6, w is [-1.9        -0.79216168  3.12332088]\n",
      "Iteration 7, w is [-1.9        -0.79216168  3.12332088]\n",
      "Iteration 8, w is [-1.9        -0.79216168  3.12332088]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Iteration 8, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 1, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 2, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 3, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 4, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 5, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 6, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 7, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 8, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 9, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 10, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 11, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 12, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 13, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 14, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 15, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 16, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 17, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 18, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 19, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 20, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 21, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 22, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 23, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 24, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 25, w is [-1.8        -0.65141794  3.2067204 ]\n",
      "Iteration 26, w is [-1.8        -0.65141794  3.2067204 ]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Iteration 26, w is [-1.9        -0.29639234  3.18625947]\n",
      "Iteration 1, w is [-1.9        -0.29639234  3.18625947]\n",
      "Iteration 2, w is [-1.9        -0.29639234  3.18625947]\n",
      "Iteration 3, w is [-1.9        -0.29639234  3.18625947]\n"
     ]
    }
   ],
   "source": [
    "X, y = generate_data()\n",
    "train_perceptron(X, y, eta=0.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Gradient Descent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "def sigmoid(x,a=1):\n",
    "    # your code here\n",
    "    return 1/(1+np.exp(-a*x))\n",
    "\n",
    "def grad_sigmoid(x, a=1):\n",
    "    # your code here\n",
    "    return sigmoid(x,a)*(1-sigmoid(x,a))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot sig functions \n",
    "xx = np.linspace(-6,6,1000)\n",
    "a_vals = [0.4,1,2,3]\n",
    "cols = ['red', 'blue', 'orange', 'green']\n",
    "y_sig = [sigmoid(xx, a_val) for a_val in a_vals]\n",
    "y_grad_sig = [grad_sigmoid(xx, a_val) for a_val in a_vals]\n",
    "\n",
    "for i in range(len(a_vals)):\n",
    "    label = str(a_vals[i])\n",
    "    plt.plot(xx, y_sig[i], label=rf'$a={label}$', color=cols[i])\n",
    "    plt.plot(xx, y_grad_sig[i], color=cols[i])\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def loss_i(w, x_i, y_i):\n",
    "    '''squared loss for i-th data point'''\n",
    "    # your code here\n",
    "    return (y_i - sigmoid(x_i,a))**2\n",
    "    \n",
    "    \n",
    "def grad_loss_i(w, x_i, y_i):\n",
    "    '''grad loss for i-th data point'''\n",
    "    # your code here\n",
    "    return (y_i - sigmoid(x_i,a)) * (-x_i) * grad_sigmoid(w@x_i)\n",
    "\n",
    "def gradient_descent(X, y, eta, T):\n",
    "    #T iterations\n",
    "    nmb_data = X.shape[0]\n",
    "    w = np.array([-2,-1,-3])\n",
    "    plot_scatter(X, y, w)\n",
    "    # your code here\n",
    "    for i in range(T):\n",
    "        loss = 0\n",
    "        grad_loss = 0\n",
    "        for t in range(nmb_data):\n",
    "            loss += loss_i(w,X[i],y[i])\n",
    "            grad_loss += grad_loss_i(w,X[i],y[i])\n",
    "        loss *= 0.5\n",
    "        w = w-eta*grad_loss"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "X, y = generate_data(50)\n",
    "gradient_descent(X, y, 0.2, 25)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Stochastic Gradient Descent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def stochastic_gradient_descent(X, y, eta, T):\n",
    "    #T iterations\n",
    "    nmb_data = X.shape[0]\n",
    "    w = np.array([-2,-1,-3])\n",
    "    plot_scatter(X, y, w)\n",
    "    # your code here\n",
    "    for i in range(T):\n",
    "        loss = 0\n",
    "        for t in range(nmb_data):\n",
    "            loss += loss_i(w,X[i],y[i])\n",
    "            w = w-eta*grad_loss\n",
    "        loss *= 0.5\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "# generate data\n",
    "X, y = generate_data()\n",
    "stochastic_gradient_descent(X, y, 0.5, 15)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
